<!doctype html>
<html>
	<head>
		<title>Working With Objects</title>
		<link rel="stylesheet" href="../lib/highlight/styles/github.css">
		<link rel="stylesheet" href="../lib/lodash-essentials.css">
		<script src="../lib/jquery.min.js"></script>
		<script src="../lib/highlight/highlight.pack.js"></script>
		<script src="../lib/lodash.js"></script>
		<script src="../lib/lodash-essentials.js"></script>
		<script src="chapter2.js"></script>
	</head>
	<body>
		<h1>Lodash Essentials</h1>
		<h2>Chapter 2 &mdash; working with objects</h2>
		<div id="container">
			<ul id="navigation">
				<li><strong>Determining Object Type</strong></li>
				<li><a href="#argumentCount">different argument counts</a></li>
				<li><a href="#argumentShift">shifting argument order</a></li>
				<li><a href="#arithmetic">doing arithmetic safely</a></li>
				<li><a href="#callable">checking for callables</a></li>
				<li><strong>Assigning and Accessing Properties</strong></li>
				<li><a href="#assign">assining objects</a></li>
				<li><a href="#assignMultiple">assigning multiple objects</a></li>
				<li><a href="#merge">merging objects</a></li>
				<li><a href="#defaults">supplying default values</a></li>
				<li><a href="#findKey">finding keys</a></li>
				<li><a href="#findKeyShorthands">finding keys with shorthands</a></li>
				<li><a href="#findKeyArray">finding keys using array values</a></li>
				<li><a href="#findPropertyValue">finding properties by value</a></li>
				<li><strong>Iterating Over Objects</strong></li>
				<li><a href="#forOwn">iterating over objects</a></li>
				<li><a href="#forIn">including inherited properties</a></li>
				<li><a href="#keys">iteratiing over object keys</a></li>
				<li><a href="#keysOrdered">ordered property access</a></li>
				<li><a href="#values">iterating over object values</a></li>
				<li><a href="#valuesOrdered">ordered property values</a></li>
				<li><strong>Calling Methods</strong></li>
				<li><a href="#results">method call or property access</a></li>
				<li><a href="#functions">finding object functions</a></li>
				<li><strong>Transforming Objects</strong></li>
				<li><a href="#pairs">key/value pairs</a></li>
				<li><a href="#pick">picking object properties</a></li>
				<li><a href="#omit">omitting object properties</a></li>
				<li><a href="#omitCallback">omitting with callbacks</a></li>
				<li><a href="#invert">inverving keys and values</a></li>
				<li><strong>Creating and Cloning Objects</strong></li>
				<li><a href="#create">creating objects</a></li>
				<li><a href="#clone">cloning objects</a></li>
			</ul>
			<div id="right">
				<h3>Code</h3>
<pre id="argumentCount" class="hidden">
<code>
function hello(name) {
	if (_.isString(name)) {
		return 'hello, ' + name;
	}   
}   

hello('world');
hello();
</code></pre>
<pre id="argumentShift" class="hidden"><code>
function hello(greeting, person) {
    if (_.isPlainObject(greeting)) {
        person = greeting;
        greeting = 'hi, ';
    }
 
    return greeting + person.name;
}   

hello('hello, ', { name: 'Dillan' }), 
hello({ name: 'Danielle' })
</code></pre>
<pre id="arithmetic" class="hidden"><code>
    var operand1 = 1/0,
        operand2 = NaN,
        results = []; 

    _.forEach([ operand1, operand2 ], function(op) {
        if (_.isFinite(op)) {
            results.push('operand 1 is finite');
        } else {
            if (!_.isNumber(op) || _.isNaN(op)) {
                results.push(op.toString() + ' is not a number');
            } else {
                results.push('Infinity cannot be used here');
            }   
        }   
    }); 

    return results;
</code></pre>
<pre id="callable" class="hidden"><code>
var object = { 
	a: function() { return 'ret'; },
	b: []
};  

_.isFunction(object.a) && object.a();
_.isFunction(object.b) && object.b();
</code></pre>
<pre id="assign" class="hidden"><code>
var object = { 
    name: 'Jeremy',
    age: 42
};  

_.assign(object, {
    occupation: 'Programmer'
});
</code></pre>
<pre id="assignMultiple" class="hidden"><code>
var object1 = { 
        name: 'Jenny',
        age: 27
    },  
    object2 = { 
        age: 31
    },  
    object3 = { 
        occupation: 'Neurologist'
    };

_.assign(object1, object2, object3);
</code></pre>
<pre id="merge" class="hidden"><code>
var object1 = { 
        states: { running: 'poweroff' },
        names: [ 'CentOS', 'REHL' ]
    },  
    object2 = { 
        states: { off: 'poweron' },
        names: [ 'Ubuntu', 'Debian' ]
    };  

_.merge(object1, object2, function(dest, src) {
    if (_.isArray(dest) && _.isArray(src)) {
        return dest.concat(src);
    }   
}); 
</code></pre>
<pre id="defaults" class="hidden"><code>
var object = { 
    name: 'George'
};  

_.defaults(object, {
    name: '', 
    age: 0,
    occupation: ''
});
</code></pre>
<pre id="findKey" class="hidden"><code>
var object = { 
    name: 'Gene',
    age: 43, 
    occupation: 'System Administrator'
};  

_.findKey(object, function(value) {
    return value === 'Gene';
});
</code></pre>
<pre id="findKeyShorthands" class="hidden"><code>
var object = { 
    programmers: {
        Keith: 'C',
        Marilyn: 'JavaScript'
    },  
    designers: {
        Lori: 'CSS',
        Marilyn: 'HTML'
    }   
};  

_.findKey(object, { Marilyn: 'JavaScript' });
</code></pre>
<pre id="findKeyArray" class="hidden"><code>
var object = { 
    Maria: [
        'Python',
        'Lisp',
        'Go'
    ],  
    Douglas: [
        'CSS',
        'Clojure',
        'Haskell'
    ]   
}, lang = 'Lisp';

_.findKey(object, function(value) {
    if (_.isArray(value)) {
        return _.contains(value, lang);
    } else {
        return value === lang;
    }   
});
</code></pre>
<pre id="findPropertyValue" class="hidden"><code>
var object = { 
    8490: {
        first: 'Arthur',
        last: 'Evans',
        enabled: false
    },  
    7035: {
        first: 'Shirley',
        last: 'Rivera',
        enabled: false
    },  
    4818: {
        first: 'William',
        last: 'Howard',
        enabled: true
    }   
};  

_.find(object, 'enabled');
_.where(object, { last: 'Rivera' });
</code></pre>
<pre id="forOwn" class="hidden"><code>
var object = { 
    name: 'Vince',
    age: 42, 
    occupation: 'Architect'
}, result = []; 

_.forOwn(object, function(value, key) {
    result.push(key + ': ' + value);
});
</code></pre>
<pre id="forIn" class="hidden"><code>
function Person() {
    this.full = function() {
        return this.first + ' ' + this.last;
    };  
}   

function Employee(first, last, occupation) {
    this.first = first;
    this.last = last;
    this.occupation = occupation;
}   

Employee.prototype = new Person();

var employee = new Employee('Theo', 'Cruz', 'Programmer'),
    resultOwn = [], 
    resultIn = []; 

_.forOwn(employee, function(value, key) {
    resultOwn.push(key);
}); 

_.forIn(employee, function(value, key) {
    resultIn.push(key);
});
</code></pre>
<pre id="keys" class="hidden"><code>
var object = { 
    occupation: 'Optometrist',
    last: 'Lynch',
    first: 'Shari'
}; 

_.sortBy(_.keys(object));
</code></pre>
<pre id="keysOrdered" class="hidden"><code>
var object = { 
    occupation: 'Optometrist',
    last: 'Lynch',
    first: 'Shari'
};  

return _.at(object, _.sortBy(_.keys(object)));
</code></pre>
<pre id="values" class="hidden"><code>
var object = { 
    first: 'Hue',
    last: 'Burton',
    occupation: 'Horticulturalist'
};  

_.values(object);
</code></pre>
<pre id="valuesOrdered" class="hidden"><code>
var object = { 
    Angular: { name: 'Patrick' },
    Ember: { name: 'Jane' },
    Backbone: { name: 'George' }
};  

_.sortBy(_.values(object), 'name');
</code></pre>
<pre id="results" class="hidden"><code>
var object1 = { 
        name: 'Brian'
    },  
    object2 = { 
        name: function() {
            return 'Brian';
        }   
    },  
    object3 = {}; 

_.result(object1, 'name', 'Brian');
_.result(object2, 'name', 'Brian');
_.result(object3, 'name', 'Brian');
</code></pre>
<pre id="functions" class="hidden"><code>
function Person(first, last) {
    this.first = first;
    this.last = last;
}   

Person.prototype.name = function() {
    return this.first + ' ' + this.last;
};  

_.functions(new Person('Teresa', 'Collins'));
</code></pre>
<pre id="pairs" class="hidden"><code>
function format(label, value) {
    return label + ': ' + value;    
}   

var object = { 
    first: 'Katherine',
    last: 'Bailey',
    age: 33
}, result = ''; 

_.forEach(_.pairs(object), function(pair) {
    result += format.apply(null, pair) + '\n';
});
</code></pre>
<pre id="pick" class="hidden"><code>
var object1 = { 
        name: 'Kevin Moore',
        occupation: 'Programmer'
    },  
    object2 = { 
        specialty: 'Python',
        employer: 'Acme'
    };  

_.assign(object1, _.pick(object2, 'specialty'));
</code></pre>
<pre id="omit" class="hidden"><code>
var object1 = { 
        name: 'Kevin Moore',
        occupation: 'Programmer'
    },  
    object2 = { 
        specialty: 'Python',
        employer: 'Acme'
    };  

_.assign(object1, _.omit(object2, 'employer'));
</code></pre>
<pre id="omitCallback" class="hidden"><code>
var object = { 
    name: 'Lois Long',
    age: 0,
    occupation: null
};  

_.omit(object, function(value) {
    return !(!_.isBoolean(value) && value);
});
</code></pre>
<pre id="invert" class="hidden"><code>
function sortValues(object) {
    return _.values(object).sort();
}   

var object1 = { 
        first: 'Mathew',
        last: 'Johnson'
    },  
    object2 = { 
        first: 'Melissa',
        last: 'Willians'
    };

sortValues(object1);
sortValues(_.invert(object2));
</code></pre>
<pre id="create" class="hidden"><code>
function Person() {}
Person.prototype.name = function() {
    return this.first + ' ' + this.last;
};  

var collection = [ 
        { first: 'Jean', last: 'Flores' },
        { first: 'Edward', last: 'Baker' },
        { first: 'Jennifer', last: 'Walker' }
    ],  
    people = []; 

_.forEach(collection, function(item) {
    people.push(_.create(Person.prototype, item));
}); 

_.invoke(people, 'name');
</code></pre>
<pre id="clone" class="hidden"><code>
function Person(first, last) {
    this.first = first;
    this.last = last;
}

var object1 = { 
        first: 'Laura',
        last: 'Gray'
    },  
    object2 = new Person('Bruce', 'Price'),
    clone1 = _.clone(object1),
    clone2 = _.clone(object2);

clone1.first === 'Laura';
clone2.first === 'Bruce' && clone2 instanceof Person;
</code></pre>
				<h3>Result</h3>
				<pre id="result"><code>
					
				</code></pre>
			</div>
		</div>
	</body>
</html>
